<?php

namespace catchAdmin\archives\controller;

use app\common\lib\Redis;
use app\common\lib\ZhyxMongo;
use app\common\model\AdvSearchParam;
use app\Request;
use catchAdmin\archives\excel\PatientExport;
use catcher\base\CatchController;
use catcher\base\CatchRequest;
use catcher\CatchResponse;
use catchAdmin\archives\service\InformationService;
use app\common\model\PatientInfo as PatientInfoModel;
use catcher\library\excel\Excel;
use catcher\Utils;
use catchAdmin\archives\request\InformationRequest;
use app\common\business\Patient as PatientBusiness;
use catcher\exceptions\FailedException;
use catchAdmin\archives\request\SavePatientInfoRequest;
use MongoDB\BSON\ObjectId;

class Information extends CatchController
{
    protected $patientInfo;

    public function __construct(PatientInfoModel $patientInfo)
    {
        $this->patientInfo = $patientInfo;
    }

    /**
     * 列表
     *
     * @time 2020年01月09日
     * @return \think\response\Json
     */
    public function index(Request $request): \think\response\Json
    {
        $req = $request->param();
        return showJson(10000, 'success', $this->patientInfo->getList());
    }

    /**
     * 保存
     *
     * @time 2020年01月09日
     * @param SavePatientInfoRequest $request
     * @return \think\response\Json
     */
    public function save(SavePatientInfoRequest $request): \think\response\Json
    {
        $ret = (new InformationService())->addPatientInfo($request->param());
        return CatchResponse::success($ret);
    }

    /**
     * 更新
     *
     * @time 2020年01月09日
     * @param $id
     * @param CatchRequest $request
     * @return \think\response\Json
     */
    public function update($id, CatchRequest $request): \think\response\Json
    {
        $req = $request->param();
        $data = [
            'name' => $req['name'],
            'sex' => $req['sex'],
            'birthdate' => $req['birthdate'],
            'inage' => isset($req['inage']) && !empty($req['inage']) ? (int)$req['inage'] : '',
            'presentTelphone' => isset($req['mobile']) && !empty($req['mobile']) ? (string)$req['mobile'] : ''
        ];
        //如果是失访患者，记录联系方式更新状态
        (new InformationService())->upLostPhoneStatus($id, $req['mobile']);

        $ret = $this->patientInfo->saveData($id, $data);
        return CatchResponse::success($ret);
    }

    /**
     * 删除
     *
     * @time 2020年01月09日
     * @param $id
     * @return \think\response\Json
     */
    public function delete($id): \think\response\Json
    {
        return CatchResponse::success($this->patientInfo->destroy($id));
    }

    /**
     * 导出
     *
     * @time 2020年09月08日
     * @param Excel $excel
     * @param PatientExport $patientExport
     * @return \think\response\Json
     * @throws \PhpOffice\PhpSpreadsheet\Exception
     */
    public function export(Excel $excel, PatientExport $patientExport, CatchRequest $request): \think\response\Json
    {
        set_time_limit(0);
        ini_set("memory_limit", "2G");
        return CatchResponse::success($excel->save($patientExport, Utils::publicPath('export/patients')));
    }

    /**
     * 手机号获取患者信息
     * @time 2023年02月07日
     * @return \think\response\Json
     */
    public function mobile_patient_info(InformationRequest $request): \think\response\Json
    {
        return CatchResponse::success((new InformationService())->getFoTelPatientInfo($request->param('mobile')));
    }

    /**
     * 电话随访-获取联系电话（本人和家庭成员）
     * @param CatchRequest $request
     * @return \think\response\Json
     */
    public function family_mobile(CatchRequest $request): \think\response\Json
    {
        $req = $request->param();

        if (!isset($req['patientId']) && empty($req['patientId'])) {
            throw new FailedException("缺少patientId");
        }
        return CatchResponse::success((new PatientBusiness())->getFamilyMembersMobile($request->param('patientId')));
    }

    /**
     * @throws \JsonException
     */
    public function advancedSearch(CatchRequest $request)
    {
        set_time_limit(0);
        $searchData = $request->param("search_data", []);
        if (empty($searchData)) {
            throw new FailedException("高级检索参数不能为空");
        }
        $searchFormData = $request->param('search_form_data', []);


        $searchData = json_decode($searchData, true, 512, JSON_THROW_ON_ERROR);

        $temp = [];
        foreach ($searchData as $k => $v) {
            foreach ($v as $kk => $vv) {
                if (is_array($vv)) {
                    $orArr = [];
                    foreach ($vv as $kkk => $vvv) {
                        $orArr[] = json_decode($vvv, true, 512, JSON_THROW_ON_ERROR);
                    }
                    $temp[] = ['$or' => $orArr];
                } else {
                    $temp[] = json_decode($vv, true, 512, JSON_THROW_ON_ERROR);
                }
            }
        }
        $condition = ['$and' => $temp];
        $redisKey = (string)new ObjectId();
        $collection = ZhyxMongo::getInstance()->setCollection('patient_info');
        $cursor = $collection->aggregate([['$match' => $condition], ['$count' => 'total_count']]);
        $result = iterator_to_array($cursor);
        $totalCount = $result[0]["total_count"] ?? 0;
        if (!empty($totalCount)) {
            //执行入库操作
            (new AdvSearchParam())->save([
                'request_id' => $redisKey,
                'search_form_data' => $searchFormData,
                'deleted_at' => 0
            ]);

            Redis::getInstance()->redis->setex("advSearch:" . $redisKey, 1800, json_encode($condition, JSON_THROW_ON_ERROR | JSON_UNESCAPED_UNICODE));
            return CatchResponse::success(["request_id" => $redisKey]);
        }
        return CatchResponse::fail("没有找到任何信息");
    }

    public function getFormDataByRequestId(CatchRequest $request, string $requestId): \think\response\Json
    {
        if (empty($requestId)) {
            throw new FailedException("requestId不能为空");
        }

        $result = (new AdvSearchParam())->where("request_id", "=", $requestId)->find();

        return CatchResponse::success($result ?? []);

    }


}